package copyengine.ui.display.s9 {
    import flash.geom.Rectangle;

    import starling.textures.Texture;

    /**
     * Slices a Starling Texture into nine regions to be used by <code>Scale9Image</code>.
     */
    public final class Scale9Textures {

        private static const HELPER_RECTANGLE:Rectangle = new Rectangle();

        /**
         * Constructor.
         *
         * @param texture        A Starling Texture to slice up into nine regions. It is recommended to turn of mip-maps for best rendering results.
         * @param scale9Grid    The rectangle defining the region in the horizontal center and vertical middle, with other regions being calculated automatically. This value should be based on the original texture dimensions, with no adjustments for scale factor.
         */
        public function Scale9Textures(texture:Texture, scale9Grid:Rectangle) {
            var textureFrame:Rectangle = texture.frame;
            if (!textureFrame) {
                textureFrame = HELPER_RECTANGLE;
                textureFrame.setTo(0, 0, texture.width, texture.height);
            }
            this.mTexture = texture;
            this.mScale9Grid = scale9Grid;
            this.initialize();
        }

        private var mTexture:Texture;
        private var mScale9Grid:Rectangle;
        private var mTopLeft:Texture;
        private var mTopCenter:Texture;
        private var mTopRight:Texture;
        private var mMiddleLeft:Texture;
        private var mMiddleCenter:Texture;
        private var mMiddleRight:Texture;
        private var mBottomLeft:Texture;
        private var mBottomCenter:Texture;
        private var mBottomRight:Texture;

        public function get texture():Texture {return this.mTexture;}

        public function get scale9Grid():Rectangle {return this.mScale9Grid;}

        public function get topLeft():Texture {return this.mTopLeft;}

        public function get topCenter():Texture {return this.mTopCenter;}

        public function get topRight():Texture {return this.mTopRight;}

        public function get middleLeft():Texture {return this.mMiddleLeft;}

        public function get middleCenter():Texture {return this.mMiddleCenter;}

        public function get middleRight():Texture {return this.mMiddleRight;}

        public function get bottomLeft():Texture {return this.mBottomLeft;}

        public function get bottomCenter():Texture {return this.mBottomCenter;}

        public function get bottomRight():Texture {return this.mBottomRight;}

        private function initialize():void {
            var textureFrame:Rectangle = this.mTexture.frame;
            if (!textureFrame) {
                textureFrame = HELPER_RECTANGLE;
                textureFrame.setTo(0, 0, this.mTexture.width, this.mTexture.height);
            }
            var leftWidth:Number = this.mScale9Grid.x;
            var centerWidth:Number = this.mScale9Grid.width;
            var rightWidth:Number = textureFrame.width - this.mScale9Grid.width - this.mScale9Grid.x;
            var topHeight:Number = this.mScale9Grid.y;
            var middleHeight:Number = this.mScale9Grid.height;
            var bottomHeight:Number = textureFrame.height - this.mScale9Grid.height - this.mScale9Grid.y;

            var regionLeftWidth:Number = leftWidth + textureFrame.x;
            var regionTopHeight:Number = topHeight + textureFrame.y;
            var regionRightWidth:Number = rightWidth - (textureFrame.width - this.mTexture.width) - textureFrame.x;
            var regionBottomHeight:Number = bottomHeight - (textureFrame.height - this.mTexture.height) - textureFrame.y;

            var hasLeftFrame:Boolean = regionLeftWidth != leftWidth;
            var hasTopFrame:Boolean = regionTopHeight != topHeight;
            var hasRightFrame:Boolean = regionRightWidth != rightWidth;
            var hasBottomFrame:Boolean = regionBottomHeight != bottomHeight;

            var topLeftRegion:Rectangle = new Rectangle(0, 0, regionLeftWidth, regionTopHeight);
            var topLeftFrame:Rectangle = (hasLeftFrame || hasTopFrame) ? new Rectangle(textureFrame.x, textureFrame.y, leftWidth, topHeight) : null;
            this.mTopLeft = Texture.fromTexture(this.mTexture, topLeftRegion, topLeftFrame);

            var topCenterRegion:Rectangle = new Rectangle(regionLeftWidth, 0, centerWidth, regionTopHeight);
            var topCenterFrame:Rectangle = hasTopFrame ? new Rectangle(0, textureFrame.y, centerWidth, topHeight) : null;
            this.mTopCenter = Texture.fromTexture(this.mTexture, topCenterRegion, topCenterFrame);

            var topRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, 0, regionRightWidth, regionTopHeight);
            var topRightFrame:Rectangle = (hasTopFrame || hasRightFrame) ? new Rectangle(0, textureFrame.y, rightWidth, topHeight) : null;
            this.mTopRight = Texture.fromTexture(this.mTexture, topRightRegion, topRightFrame);

            var middleLeftRegion:Rectangle = new Rectangle(0, regionTopHeight, regionLeftWidth, middleHeight);
            var middleLeftFrame:Rectangle = hasLeftFrame ? new Rectangle(textureFrame.x, 0, leftWidth, middleHeight) : null;
            this.mMiddleLeft = Texture.fromTexture(this.mTexture, middleLeftRegion, middleLeftFrame);

            var middleCenterRegion:Rectangle = new Rectangle(regionLeftWidth, regionTopHeight, centerWidth, middleHeight);
            this.mMiddleCenter = Texture.fromTexture(this.mTexture, middleCenterRegion);

            var middleRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, regionTopHeight, regionRightWidth, middleHeight);
            var middleRightFrame:Rectangle = hasRightFrame ? new Rectangle(0, 0, rightWidth, middleHeight) : null;
            this.mMiddleRight = Texture.fromTexture(this.mTexture, middleRightRegion, middleRightFrame);

            var bottomLeftRegion:Rectangle = new Rectangle(0, regionTopHeight + middleHeight, regionLeftWidth, regionBottomHeight);
            var bottomLeftFrame:Rectangle = (hasLeftFrame || hasBottomFrame) ? new Rectangle(textureFrame.x, 0, leftWidth, bottomHeight) : null;
            this.mBottomLeft = Texture.fromTexture(this.mTexture, bottomLeftRegion, bottomLeftFrame);

            var bottomCenterRegion:Rectangle = new Rectangle(regionLeftWidth, regionTopHeight + middleHeight, centerWidth, regionBottomHeight);
            var bottomCenterFrame:Rectangle = hasBottomFrame ? new Rectangle(0, 0, centerWidth, bottomHeight) : null;
            this.mBottomCenter = Texture.fromTexture(this.mTexture, bottomCenterRegion, bottomCenterFrame);

            var bottomRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, regionTopHeight + middleHeight, regionRightWidth, regionBottomHeight);
            var bottomRightFrame:Rectangle = (hasBottomFrame || hasRightFrame) ? new Rectangle(0, 0, rightWidth, bottomHeight) : null;
            this.mBottomRight = Texture.fromTexture(this.mTexture, bottomRightRegion, bottomRightFrame);
        }
    }
}
